package vo;

import operator.Handler;
import platform.MeanLabel;
import common.Constant;
import common.Singleton;
import view.Main;

import java.util.TreeMap;

/**
 * Mean是一个意象，包含文字信息和位置、属性
 *
 * @author 柴家琪
 */
public class Mean implements Comparable<Mean> {
    public static int important_type = -1; // 重要属性。据此查找重要属性为空的项，-1代表查找全部

    private Mean main;
    private Handler handler;
    private String text, description = "";
    // 对于Integer,TreeSet自动排序且不重复
//	private TreeSet<Integer> locations = new TreeSet<>();// locations包含了所有的位置，方便排序 // Disappear Locations
    private int location;
    private int offsetsSum = 0;
    private Mean nextMean, lastMean;
    private int group_id, inner_id;
    private int suitPage; // 适合页
    private int pageFrom; // 在适合页中的位置

    private Main m;

    public int index_in_full_text;
    private String attributes[] = new String[Singleton.main().attrsName.length];
    {
        for (int i = 0; i < attributes.length; i++) {
            attributes[i] = "";
        }
    }
    private MeanLabel label;

    private Mean() {
        m = Singleton.main();
        handler = Singleton.handler();
    }

    /**
     * 主意象，传入组id 设置好参数就行，不用手动添加到集合 如果传入的suitPage为0，将会自动在setDescription()中修正
     */
    public Mean(String text, int from, int group_id) {
        this();

        suitPage = m.presentPage;
        pageFrom = from;

        main = this;
        handler = Singleton.handler();
        this.text = text;
        this.group_id = group_id;
        // this.handler=handler;
        inner_id = 0;
        location = from + (m.presentPage <= 1 ? 0 : handler.getPgs().get(m.presentPage - 1));
        handler.mainMean.add(this);
        handler.allMean.add(this);

    }

    public static void turnToMain(Mean mean) {
        Handler handler = Singleton.handler();

        mean.group_id = Singleton.handler().getGroupId();
        mean.inner_id = 0;
        mean.offsetsSum = 0;
        mean.main = mean;
        mean.nextMean = null;
        mean.lastMean = null;
        handler.mainMean.add(mean);
        if (!handler.allMean.contains(mean))// 如果是新添加意象
            handler.allMean.add(mean);
    }

    /**
     * 临时标记
     */
    public Mean(String text, int from) {
        this();

        this.text = text;
        // this.handler=handler;
        location = from + (m.presentPage <= 1 ? 0 : handler.getPgs().get(m.presentPage - 1));
        suitPage = m.presentPage;
        pageFrom = from;
    }

    private void turnToViceOf(Mean main) {
        if (this.haveNext())
            getNext().turnToViceOf(main);
        handler.deleteMean(this);// 先删除，再添加
        main.addNext(this);
    }

    /**
     * 使变为副意象
     */
    public void turnMainToViceOf(Mean main) {
        if (getInner_id() == 0) {
            turnToViceOf(main);
        } else {
            handler.deleteMean(this);
            main.addNext(this);
        }
    }

    public void addLocation(int from) {
        location = from;
    }
    public Mean addNext(String text, int from) {
        return addNext(new Mean(text, from));
    }

    public Mean addNext(Mean mean) {
        Mean temp = this;
        while (temp.getNext() != null) {
            if (temp.getNext().getTop() >= mean.getTop())
                break;
            temp = temp.getNext();
        }
        mean.setNext(temp.getNext());
        temp.setNext(mean);
        mean.main = this.main;
        mean.group_id = this.group_id;
        mean.inner_id = ++main.offsetsSum;// 保证每个副意象的inner_id不同
        handler.allMean.add(mean);
        return mean;
    }

    public Mean getNext() {
        return nextMean;
    }

    public Mean getLast() {
        return lastMean;
    }

    public void setNext(Mean mean) {
        nextMean = mean;
        if (mean != null)
            mean.lastMean = this;
    }

    public void setDescription() {
        description = "";
        TreeMap<Integer, Integer> pgs = handler.getPgs();


        int suitPageRecord = -1;
        for (Integer page: pgs.keySet()) {
            if (location < pgs.get(page)) {
                suitPageRecord = page;
                break;
            }
        }
        // 修正suitPage及pageFrom
        suitPage = suitPageRecord;
        pageFrom = location - (suitPage == 1 ? 0 : handler.getPgs().get(suitPage - 1));

        description = suitPage + "段";
    }

    public int getTop() {
        return location;
    }

    public Mean getMain() {
        return main;
    }

    public String getTextForShow() {
        if(text.length() < 12) {
            return text;
        }

        return text.substring(0, 10) + "...";
    }

    public String getText() {
        return text;
    }

    public String getDescription() {
        return description;
    }


    public void setLocation(int location) {
        this.location = location;
    }

    public Integer getLocation() {
        return location;
    }
    public int getGroup_id() {
        return group_id;
    }

    public void setGroup_id(int group_id) {
        this.group_id = group_id;
    }

    public int getInner_id() {
        return inner_id;
    }

    public int getLength() {
        if (text != null)
            return text.length();
        return 0;
    }

    public MeanLabel getLabel() {
        return label;
    }

    public void setLabel(MeanLabel label) {
        this.label = label;
    }

    public int getSuitPage() {
        return suitPage;
    }

    public void setSuitPage(int suitPage) {
        this.suitPage = suitPage;
    }

    public boolean haveNext() {
        return nextMean != null;
    }

    public boolean isHidden() {
        return text.equals(Constant.HIDDEN);
    }

    public Mean getLastMean() {
        return lastMean;
    }

    public void setLastMean(Mean lastMean) {
        this.lastMean = lastMean;
    }

    public int getPageFrom() {
        return pageFrom;
    }

    public void setPageFrom(int pageFrom) {
        this.pageFrom = pageFrom;
    }

    @Override
    public int compareTo(Mean o) {
        if (this.getTop() > o.getTop())
            return 1;
        return -1;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + group_id;
        result = prime * result + inner_id;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Mean other = (Mean) obj;
        return group_id == other.group_id && inner_id == other.inner_id;
    }

    /**
     * OLD to NEW Translate 升级测试
     */
    public void setAttribute(String attrs[]) {
        attributes = attrs;
    }

    /**
     * 版本分拨
     */
    public void setPointedAttr(String str, int type, String version) {
        if (version.equals("1.4"))
            setPointedAttr_version1_4(str, type);
        else if (version.startsWith("1.3"))
            setPointedAttr_version1_3(str, type);
        else if (version.startsWith("1.0") || version.equals("source"))
            setPointedAttr_version1_0(str, type);
    }

    /**
     * 当前版本
     */
    private void setPointedAttr(String str, int type) {
        if (type > 0 && type <= attributes.length)// error point:数组操作错误！
            attributes[type - 1] = str;
    }

    /**
     * 1.4版本属性<br/>
     * 篇章名,段落号,句子号,小句号,所在位置,句法位置,指称类型7,句法功能8,
     * 【名词类,指示词类,代词类,零形代词类】9,结构类型10,语义功能（类型）11,词语的性12,词语的数13<br/>
     */
    private void setPointedAttr_version1_4(String str, int type) {
        setPointedAttr(str, type);// 若有新的属性版本，此方法写入转换且此处转新的方法
    }

    /**
     *
     * 1.3版本属性<br/>
     * 篇章名,段落号,句子号,小句号,所在位置,句法位置,词性7,句法功能8,词语类型9,结构类型10,语义类型11<br/>
     * -->1.4（去除词性-7）
     */
    private void setPointedAttr_version1_3(String str, int type) {
        if (type == 7)
            return;
        setPointedAttr_version1_4(str, type);
    }

    /**
     * 1.0版本属性 -->1.3
     */
    private void setPointedAttr_version1_0(String str, int type) {
        int real = type;
        switch (type) {
            case 1:
                real = 5;
                break;
            case 2:
                real = 6;
                break;
            case 3:
                real = 8;
                break;
            case 4:
                real = 7;
                break;
            case 5:
                real = 1;
                break;
            case 6:
                real = 3;
                break;
            case 7:
                real = 4;
                break;
            case 8:
                real = 10;
                break;
            case 9:
                real = 11;
                break;
        }
        setPointedAttr_version1_3(str, real);
    }

    public String[] getAttributes() {
        return attributes;
    }

    /**
     * 检查是否所有属性都有值，并改变对应颜色
     */
    public void changeMeanBorder() {
        label.setBorderColor(isFulled());
    }

    /**
     * 检查是否所有属性都有值
     */
    public boolean isFulled() {
        if (important_type == -1) {
            for (String s : attributes) {
                if (badString(s)) {
                    return false;
                }
            }
        } else {
            return !badString(attributes[important_type]);
        }
        return true;
    }

    private boolean badString(String s) {
        return s == null || s.equals("");
    }
}